#ifndef HJX_H_INCLUDED
#define HJX_H_INCLUDED



#endif // HJX_H_INCLUDED
namespace hjx
{
    class string
    {
    public:
        typedef char * iterator;
        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str+_size;
        }
        string(const char *str="")
        :_str(new char[strlen(str)+1])
        {
             strcpy(_str,str);
            _size=strlen(str);
            _capacity=_size;
//            _str=new char[_capacity+1];


        }
        //拷贝构造和赋值现代写法
        //s2(s1);
        string(const string &s)
        :_str(nullptr)
        ,_size(0)
        ,_capacity(0)
        {
            string tmp(s._str);
            this->swap(tmp);
        }
        //s1=s2;
        string& operator=(string s)
        {
            this->swap(s);
            return *this;
        }
        void swap(string &s)
        {
            ::swap(_str,s._str);
            ::swap(_size,s._size);
            ::swap(_capacity,s._capacity);

        }
        ~string()
        {
            delete[] _str;
            _str=nullptr;
            _size=_capacity=0;
        }
        size_t size()const
        {
            return _size;
        }
        size_t capacity()const
        {
            return _capacity;
        }
        char& operator[](size_t i)const
        {
            return _str[i];
        }
        const char*c_str()
        {
            return _str;
        }
        void reserve(size_t newcapacity)
        {
            if(newcapacity>_capacity)
            {
                char *tmp=new char[newcapacity];
                strcpy(tmp,_str);
                delete[]_str;
                _str=tmp;
                _capacity=newcapacity;
            }

        }
        void push_back(char a)
        {
            if(_size==_capacity)
            {
                int newcapacity=_capacity==0?2:2*_capacity;
                reserve(newcapacity);
//                char *tmp=new char[newcapacity];
//                strcpy(tmp,_str);
//                delete[]_str;
//                _str=tmp;
//                _capacity=newcapacity;
            }
            _str[_size]=a;
            _size++;
            _str[_size]='\0';
        }
        void append(const char *a)
        {
            int len=strlen(a);
            if(_size+len==_capacity)
            {
                int newcapacity=_size+len;
                reserve(newcapacity);
//                char *tmp=new char [newcapacity];
//                strcpy(tmp,_str);
//                delete []_str;
//                _str=tmp;
//                _capacity=newcapacity;
            }
            strcat(_str,a);
            _size+=len;
        }
        string& operator+=(const char a)
        {
            this->push_back(a);
            return *this;
        }
        string& operator+=(const char *a)
        {
            this->append(a);
            return *this;
        }
        string& insert(size_t pos,char ch)
        {
            if(_size==_capacity)
            {
                int newcapacity=_capacity==0?2:2*_capacity;
                reserve(newcapacity);
            }
            int end1=strlen(_str);
            while(end1>=pos)
            {
                _str[end1+1]=_str[end1];
                end1--;
            }
            _str[pos]=ch;
            _size++;
            return *this;
        }
        string& insert(size_t pos,char*ch)
        {
            int len=strlen(ch);
            if(_size+len>_capacity)
            {
                int newcapacity=_size+len;
                reserve(newcapacity);
            }
            int end1=_size;
            while(end1>=(int)pos)
            {
                _str[end1+len]=_str[end1];
                end1--;
            }
            strncpy(_str+pos,ch,len);
            _size+=len;
            return *this;
        }
        void resize(size_t n,char ch='\0')
        {
            if(n<_size)
            {
                _str[n]='\0';
                _size=n;
            }
            else
            {
                if(n>_capacity)
                {
                    reserve(n);
                }
                while(_size<n)
                {
                    _str[_size]=ch;
                    _size++;
                }
            }

        }
        void erase(size_t pos,size_t n=npos)
        {
            int len=_size-pos;
            if(len<=n)
            {
                _str[pos]='\0';
                _size=pos;
            }

            else
            {
                int start=pos+n;
                while(start<_size)
                {
                    _str[start-n]=_str[start];
                    start++;
                }
                _size-=n;
                _str[_size]='\0';
            }
        }
        size_t find(char a,size_t pos=0)
        {
            for(size_t i=pos;i<_size;i++)
            {
                if(a==_str[i])
                {
                    return i;
                }
            }
            return npos;
        }
        size_t find(char *a,size_t pos=0)
        {
            char *p=strstr(_str,a);
            if(p==nullptr)
            {
                return npos;
            }
            else
            {
                return p-_str;
            }
        }
        bool operator<(const string &s)
        {
            int ret=strcmp(_str,s._str);
            return ret<0;
        }
        bool operator==(const string&s)
        {
            int ret=strcmp(_str,s._str);
            return ret==0;
        }
        bool operator<=(const string&s)
        {
            return *this<s||*this==s;
        }
        bool operator>(const string&s)
        {
            return !(*this<=s);
        }
        bool operator>=(const string&s)
        {
            return !(*this<s);
        }
        bool operator!=(const string&s)
        {
            return !(*this==s);
        }
        //cin

    private:
        char*_str;
        int _size;
        int _capacity;
        static size_t npos;
    };
    size_t string::npos=-1;
    ostream& operator<<(ostream&out,const string&s)//cout<<的重载
{
    for(size_t i=0;i<s.size();i++)
    {
         cout<<(s[i]);
    }
    return out;
}
    istream& operator>>(istream&in, string&s)
    {
        while(1)
        {
           char  ch=in.get();
            if( ch==' '||ch=='\n')
            {
                break;
            }
            else
            {
                s+=ch;
            }
        }
        return in;
    }
    void text1()
    {
      string s1;
      string s2("hello");
      cout<<s1<<endl;
      cout<<s2<<endl;
      cout<<s1.c_str()<<endl;
      cout<<s2.c_str()<<endl;
      //三种遍历方式
      for(size_t i=0;i<s2.size();i++)
      {
          s2[i]+=1;
          cout<<s2[i];
      }
      cout<<endl;
      string::iterator it2=s2.begin();
      while(it2!=s2.end())
      {
          *it2-=1;
          cout<<*it2;
          it2++;
      }
      cout<<endl;
      for(auto e:s2)
      {
          cout<<e;
      }
      cout<<endl;
    }
    void text2()
    {
        string s1;
        s1.push_back('a');
        s1.append("hjx");
        cout<<s1<<endl;
        string s2;
        s2+='s';
        s2+=' ';
        s2+="hjx";
        cout<<s2<<endl;
    }
    void text3()
    {
        string s1("hello");
        s1.insert(2,'e');
        cout<<s1<<endl;
    }
    void text4()
    {
        string s1("hjx");
        s1.insert(0,"yyds");
        cout<<s1<<endl;
    }
    void text5()
    {
        string s1("hjx");
        s1.resize(8,'x');
        cout<<s1<<endl;
    }
    void text6()
    {
        string s1("yydshjx");
        s1.erase(2,3);
        cout<<s1<<endl;
    }
    void text7()
    {
        string s1("hjxyyds");
        cout<<s1.find('y')<<endl;
        cout<<s1.find("yyds")<<endl;
    }
}
